package main

import (
	"fmt"
	"time"
)

// 利用协程求素数
func main() {
	intChan := make(chan int, 1000)
	primeChan := make(chan int, 2000) //放入结果
	//标识退出的管道
	exitChan := make(chan bool, 4) //使用4个管道

	start := time.Now()
	//开启一个协程，往管道放数据
	go putInt(intChan)
	//time.Sleep(time.Second * 3)
	//开启4个协程，并判断是否为素数，如果是就放入到primeChan中
	for i := 0; i < 4; i++ {
		go primeNum(intChan, primeChan, exitChan)
	}
	go func() {
		for i := 0; i < 4; i++ {
			<-exitChan
		}
		close(primeChan)
	}()
	for {
		res, ok := <-primeChan
		if !ok {
			break
		}
		//将结果输出
		fmt.Printf("素数=%d\n", res)
	}
	fmt.Println("主线程退出")
	end := time.Now()
	fmt.Println("总的时间耗时：", end.Sub(start).Milliseconds())
}

func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
	//使用for循环进行判断
	//var num int
	var flag bool
	for {
		num, ok := <-intChan
		if !ok {
			break
		}
		flag = true
		//判断num是否是素数
		for i := 2; i < num; i++ {
			if num%i == 0 { //说明不是素数
				flag = false
				break
			}
		}
		if flag {
			primeChan <- num
		}
	}
	fmt.Println("读不到数据退出")
	exitChan <- true
}

func putInt(intChan chan int) {
	for i := 1; i <= 800; i++ {
		intChan <- i
	}
	//管道关闭
	close(intChan)
}
